package com.gym.service.user.impl;

import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.gym.VO.ResultVO;
import com.gym.VO.user.PageVO;
import com.gym.VO.user.UserVO;
import com.gym.constant.Constant;
import com.gym.converter.UpdatePasswordForm2UserBaseInfoConvert;
import com.gym.converter.UserBaseInfoDTO2UserBaseInfoConvert;
import com.gym.dto.user.UserBaseInfoDTO;
import com.gym.enums.ResultEnum;
import com.gym.form.user.UpdatePasswordForm;
import com.gym.mapper.user.UserBaseInfoMapper;
import com.gym.mapper.user.UserDetailInfoMapper;
import com.gym.pojo.user.UserBaseInfo;
import com.gym.pojo.user.UserBaseInfoExample;
import com.gym.pojo.user.UserDetailInfo;
import com.gym.pojo.user.UserDetailInfoExample;
import com.gym.service.user.UserService;
import com.gym.utils.EncryptionUtil;
import com.gym.utils.RandomUtils;
import com.gym.utils.ResultVOUtil;
import com.gym.utils.UserValidate;

@Service
// @Slf4j
public class UserServiceImpl implements UserService {

	private Logger log = LoggerFactory.getLogger(this.getClass());

	@Autowired
	private UserBaseInfoMapper userBaseInfoMapper;

	@Autowired
	private UserDetailInfoMapper userDetailInfoMapper;

	@Override
	public ResultVO addUserBaseInfo(UserBaseInfoDTO userBaseInfoDTO) {
		UserBaseInfo userBaseInfo = null;
		try {
			// 用户名不能为空
			if (UserValidate.isNull(userBaseInfoDTO.getUserName())) {
				return ResultVOUtil.error(ResultEnum.USER_NAME_IS_NULL);
			}

			// 判断用户名格式是否正确（必须包含字母和数字）
			if (!UserValidate.isNumericAndLetter(userBaseInfoDTO.getUserName())) {
				return ResultVOUtil
						.error(ResultEnum.USER_NAME_FORMAT_IS_ILLEGAL);
			}

			// 判断用户名长度(6-16)
			if (!UserValidate.isLengthRequired(Constant.USER_NAME_MIN_LENGTH,
					Constant.USER_NAME_MAX_LENGTH,
					userBaseInfoDTO.getUserName())) {
				return ResultVOUtil
						.error(ResultEnum.USER_NAME_LENGTH_IS_ILLEGAL);
			}

			// 判断用户名是否已经被注册
			if (getUserBaseInfoByName(userBaseInfoDTO.getUserName()) != null) {
				return ResultVOUtil.error(ResultEnum.USER_HAS_EXIST);
			}

			// 密码不能为空
			if (UserValidate.isNull(userBaseInfoDTO.getUserPassword())) {
				return ResultVOUtil.error(ResultEnum.USER_PASSWORD_IS_NULL);
			}

			// 判断密码长度(6-20之间)
			if (!UserValidate.isLengthRequired(Constant.PASSWORD_MIN_LENGTH,
					Constant.PASSWORD_MAX_LENGTH,
					userBaseInfoDTO.getUserPassword())) {
				return ResultVOUtil
						.error(ResultEnum.PASSWORD_LENGTH_IS_ILLEGAL);
			}

			// 密码格式错误(密码只能使用英文字母、数字以及-和_，并且首字符必须为字母或数字 密码首字符必须为字母或数字)
			if (!UserValidate.checkUserNamePassword(userBaseInfoDTO
					.getUserPassword())) {
				return ResultVOUtil
						.error(ResultEnum.PASSWORD_FORMAT_IS_ILLEGAL);
			}

			// 判断用户密码和再次输入密码是否一致
			if (!userBaseInfoDTO.getUserPassword().equals(
					userBaseInfoDTO.getSecondPassword())) {
				return ResultVOUtil
						.error(ResultEnum.PASSWORD_AND_SECONDPASSWORD_IS_NOT_CONSISTENT);
			}

			userBaseInfo = UserBaseInfoDTO2UserBaseInfoConvert
					.convert(userBaseInfoDTO);

			// 生成用户id
			Long userId = Long.parseLong(RandomUtils.generateNum(18));
			userBaseInfo.setUserId(userId);

			// 密码加密
			userBaseInfo.setUserPassword(EncryptionUtil.getEncryption(
					userBaseInfo.getUserPassword(), userBaseInfo.getUserName(),
					Constant.ENCRYPTION_TIMES));
			// 添加新用户
			this.userBaseInfoMapper.insertSelective(userBaseInfo);

		} catch (Exception e) {
			log.error("UserServiceImpl-addUserBaseInfo出现未知异常： "
					+ e.getMessage());
			return ResultVOUtil.error(ResultEnum.UNKNOW_EXCEPTION);
		}
		return ResultVOUtil.success(userBaseInfo);
	}

	@Override
	public ResultEnum addUserDetailInfo(UserDetailInfo userDetailInfo) {
		try {
			// 手机号码判空
			if (UserValidate.isNull(userDetailInfo.getPhoneNumber() + "")) {
				return ResultEnum.USER_TEL_IS_NULL;
			}

			// 手机号码格式不正确
			if (!UserValidate.isHandset(userDetailInfo.getPhoneNumber() + "")) {
				return ResultEnum.TEL_FORMAT_ERROR;
			}

			// 判断手机号码是否已经被注册
			if (this.getUserDetailInfoByPhoneNumber(userDetailInfo
					.getPhoneNumber()) != null) {
				return ResultEnum.USER_TEL_HAS_BEEN_REGISTED;
			}

			this.userDetailInfoMapper.insert(userDetailInfo);

		} catch (Exception e) {
			log.error("UserServiceImpl-addUserDetailInfo出现未知异常： "
					+ e.getMessage());
			return ResultEnum.UNKNOW_EXCEPTION;
		}
		return ResultEnum.SUCCESS;
	}

	@Override
	public ResultEnum deleteUserBaseInfo(Long userId) {
		try {
			this.userBaseInfoMapper.deleteByPrimaryKey(userId);
			return ResultEnum.SUCCESS;
		} catch (Exception e) {
			log.error("UserServiceImpl-deleteUserBaseInfo出现未知异常："
					+ e.getMessage());
			return ResultEnum.UNKNOW_EXCEPTION;
		}
	}

	@Override
	public ResultEnum deleteUserDetailInfo(Long userId) {
		try {
			this.userDetailInfoMapper.deleteByPrimaryKey(userId);
			return ResultEnum.SUCCESS;
		} catch (Exception e) {
			log.error("UserServiceImpl-deleteUserBaseInfo出现未知异常："
					+ e.getMessage());
			return ResultEnum.UNKNOW_EXCEPTION;
		}
	}

	@Override
	public ResultEnum updatePassword(UpdatePasswordForm updatePasswordForm) {
		// 密码不能为空
		if (UserValidate.isNull(updatePasswordForm.getUserPassword())) {
			return ResultEnum.USER_PASSWORD_IS_NULL;
		}

		// 判断密码长度(6-20之间)
		if (!UserValidate.isLengthRequired(Constant.PASSWORD_MIN_LENGTH,
				Constant.PASSWORD_MAX_LENGTH,
				updatePasswordForm.getUserPassword())) {
			return ResultEnum.PASSWORD_LENGTH_IS_ILLEGAL;
		}

		// 密码格式错误(密码只能使用英文字母、数字以及-和_，并且首字符必须为字母或数字 密码首字符必须为字母或数字)
		if (!UserValidate.checkUserNamePassword(updatePasswordForm
				.getUserPassword())) {
			return ResultEnum.PASSWORD_FORMAT_IS_ILLEGAL;
		}

		// 判断用户密码和再次输入密码是否一致
		if (!updatePasswordForm.getUserPassword().equals(
				updatePasswordForm.getSecondPassword())) {
			return ResultEnum.PASSWORD_AND_SECONDPASSWORD_IS_NOT_CONSISTENT;
		}

		UserBaseInfo userBaseInfo = UpdatePasswordForm2UserBaseInfoConvert
				.convert(updatePasswordForm);

		UserBaseInfo originUser = getUserBaseInfoById(userBaseInfo.getUserId());

		userBaseInfo.setUserPassword(EncryptionUtil.getEncryption(
				userBaseInfo.getUserPassword(), originUser.getUserName(),
				Constant.ENCRYPTION_TIMES));
		return updateUserBaseInfo(userBaseInfo);
	}

	@Override
	public ResultEnum updateUserBaseInfo(UserBaseInfo userBaseInfo) {
		try {
			this.userBaseInfoMapper.updateByPrimaryKeySelective(userBaseInfo);
		} catch (Exception e) {
			log.error("UserServiceImpl-updateUserBaseInfo出现未知异常："
					+ e.getMessage());
			return ResultEnum.UNKNOW_EXCEPTION;
		}
		return ResultEnum.SUCCESS;
	}

	@Override
	public ResultEnum updateUserDetailInfo(UserDetailInfo userDetailInfo) {
		try {
			if (!UserValidate.isNull(userDetailInfo.getPhoneNumber())) {
				// 手机号码格式不正确
				if (!UserValidate.isHandset(userDetailInfo.getPhoneNumber())) {
					return ResultEnum.TEL_FORMAT_ERROR;
				}

				// 判断手机号码是否已经被注册
				UserDetailInfo detailInfo = this
						.getUserDetailInfoByPhoneNumber(userDetailInfo
								.getPhoneNumber());
				if (detailInfo != null
						&& detailInfo.getUserId() != userDetailInfo.getUserId()) {
					return ResultEnum.USER_TEL_HAS_BEEN_REGISTED;
				}
			}
			this.userDetailInfoMapper
					.updateByPrimaryKeySelective(userDetailInfo);
		} catch (Exception e) {
			log.error("UserServiceImpl-updateUserDetailInfo出现未知异常："
					+ e.getMessage());
			return ResultEnum.UNKNOW_EXCEPTION;
		}
		return ResultEnum.SUCCESS;
	}

	@Override
	public UserBaseInfo getUserBaseInfoById(Long userId) {
		return userBaseInfoMapper.selectByPrimaryKey(userId);
	}

	@Override
	public UserBaseInfo getUserBaseInfoByName(String userName) {
		UserBaseInfoExample userBaseInfoExample = new UserBaseInfoExample();
		UserBaseInfoExample.Criteria criteria = userBaseInfoExample
				.createCriteria();
		criteria.andUserNameEqualTo(userName);
		List<UserBaseInfo> baseInfos = this.userBaseInfoMapper
				.selectByExample(userBaseInfoExample);
		if (CollectionUtils.isEmpty(baseInfos))
			return null;
		return baseInfos.get(0);
	}

	@Override
	public UserDetailInfo getUserDetailInfoById(Long userId) {
		return userDetailInfoMapper.selectByPrimaryKey(userId);
	}

	@Override
	public UserDetailInfo getUserDetailInfoByPhoneNumber(String phoneNumber) {
		UserDetailInfoExample userDetailInfoExample = new UserDetailInfoExample();
		UserDetailInfoExample.Criteria criteria = userDetailInfoExample
				.createCriteria();
		criteria.andPhoneNumberEqualTo(phoneNumber);
		List<UserDetailInfo> userDetailInfos = userDetailInfoMapper
				.selectByExample(userDetailInfoExample);
		if (userDetailInfos.size() > 0) {
			return userDetailInfos.get(0);
		}
		return null;
	}

	@Override
	public UserDetailInfo getUserDetailInfoByStudentId(String studentId) {
		UserDetailInfoExample userDetailInfoExample = new UserDetailInfoExample();
		UserDetailInfoExample.Criteria criteria = userDetailInfoExample
				.createCriteria();
		criteria.andStudentIdEqualTo(studentId);
		List<UserDetailInfo> userDetailInfos = userDetailInfoMapper
				.selectByExample(userDetailInfoExample);
		if (userDetailInfos.size() > 0) {
			return userDetailInfos.get(0);
		}
		return null;
	}

	@Override
	public PageVO pageInfos(int currentPage, int pageSize) {

		PageHelper.startPage(currentPage, pageSize);

		UserBaseInfoExample userBaseInfoExample = new UserBaseInfoExample();
		UserBaseInfoExample.Criteria criteria = userBaseInfoExample
				.createCriteria();
		criteria.andUserIdNotEqualTo(-1L);
		List<UserBaseInfo> baseInfos = userBaseInfoMapper
				.selectByExample(userBaseInfoExample);

		List<UserVO> userVOs = null;

		if (!CollectionUtils.isEmpty(baseInfos)) {
			userVOs = new ArrayList<UserVO>();
			for (UserBaseInfo userBaseInfo : baseInfos) {
				UserVO userVO = new UserVO();
				BeanUtils.copyProperties(userBaseInfo, userVO);
				userVOs.add(userVO);
			}
		}

		PageInfo pageInfo = new PageInfo(baseInfos);
		PageVO pageVO = new PageVO();
		pageVO.setCurrentPage(pageInfo.getPageNum());
		pageVO.setPageSize(pageInfo.getPageSize());
		pageVO.setTotalPages(pageInfo.getPages());
		pageVO.setList(userVOs);

		return pageVO;

	}

}
